运输层:

  • 运输层为相互通信的应用进程提供逻辑通信
  • 端口和套接字的意义
  • 无连接的UDP的特点
  • 面向连接的TCP的特定
  • 在不可靠的网络上实现可靠传输的工作原理,停止等待协议和ARQ协议
  • TCP的滑动窗口、流量控制、拥塞控制和连接管理

运输层协议概述

运输层向上面的应用层提供通信服务。当网络的边缘部分的两台主机使用网络的核心部分的功能进行端到端的通信时,只有主机的协议栈才有运输层,而网络核心部分中的路由器在转发分组时都只用到下三层的功能。

两台主机进行通信就是两台主机中的应用进程互相通信,通信的真正端点并不是主机而是主机中的进程。

image-20201029205358115

网络层为主机之间提供逻辑通信,而运输层为应用进程之间提供端到端的逻辑通信

image-20201029210330272

运输层还要对收到的报文进行差错检测

TCP/IP运输层的两个主要协议都是互联网的正式标准:

  • 用户数据报协议UDP
  • 传输控制协议TCP

image-20201029210344256

两个对等运输实体在通信时传送的数据单元叫做运输协议数据单元TPDU。但在TCP/IP体系中,根据所使用的协议是TCP或UDP,分别称之为TCP报文段UDP用户数据报

image-20201029211216165

运输层的复用和分用:

  • 复用:应用层所有的应用进程都可以通过运输层再传送到IP层(网络层)
  • 分用:运输层从IP层收到发送给各应用进程的数据后,必须分别交付指明的各应用进程

硬件端口是不同硬件设备进行交互的接口,软件端口是应用层的各种协议进程与运输实体进行层间交互的一种地址。

TCP/IP的运输层用一个16位端口号来标志一个端口,端口号只有本地意义,它只是为了标志本计算机应用层中的各个进程在和运输层交互时的层间接口。

运输层的端口号分为两大类:

  • 服务器端使用的端口号

    • 熟知端口号:又称系统端口号,数值为0~1023,由IANA为应用程序指派
    • 登记端口号:数值为1024~49151,使用时要在IANA按照规定的手续登记,防止重复

    image-20201029212820764

  • 客户端使用的端口号:又称为短暂端口号,数值为49152~65535

用户数据报协议UDP

UDP的主要特点是:

  • UDP是无连接的

  • UDP使用尽最大努力交付

  • UDP是面向报文的。发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。

    image-20201029225417038

  • UDP没有拥塞控制

  • UDP支持一对一、一对多、多对一和多对多的交互通信

  • UDP的首部开销小,只有8个字节,比TCP的20个字节的首部要短

用户数据报UDP有两个字段:

  • 数据字段
  • 首部字段:8个字节,由四个字段组成,每个字段2个字节:
    • 源端口:源端口号。在需要对方回信时选用。不需要时可用全0
    • 目的端口:目的端口号。这在终点交付报文时必须使用
    • 长度:UDP用户数据报的长度,其最小值是8(仅有首部)
    • 检验和:检测UDP用户数据报在传输中是否有错。有错就丢弃

image-20201029225431486

当运输层从IP层收到UDP数据报时,就根据首部中的目的端口,把UDP数据报通过相应的端口,上交最后的终点——应用进程。

image-20201029225656203

如果接收方UDP发现收到的报文中的目的端口号不正确,就丢弃该报文,并由网际控制报文协议ICMP发送“端口不可达”差错报文给发送方。

UDP用户数据报在计算检验和时,要在UDP用户数据报之前增加12个字节的伪首部,这是在计算检验和时临时添加在UDP用户数据报前面,得到一个临时的UDP用户数据报。检验和就是按照这个临时的UDP用户数据报来计算的。伪首部既不向下传送也不向上递交,仅仅是为了计算检验和。

IP数据报的检验和只检验IP数据报的首部,但UDP的检验和是把首部和数据部分一起都检验。

传输控制协议TCP概述

TCP最主要的特点:

  • TCP是面向连接的传输层协议
  • 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的(一对一)
  • TCP提供可靠交付的服务
  • TCP提供全双工通信
  • 面向字节流。TCP中的“流”指的是流入到进程或从进程流出的字节序列。“面向字节流”的含义是:虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构字节流。TCP不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系,但接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。

image-20201030172956309

TCP连接是一条虚连接(也就是逻辑连接),而不是一条真正的物理连接。

TCP并不关心应用程序一次把多长的报文发送到TCP的缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP发送的报文长度是应用程序给出的)。

TCP把连接作为最基本的抽象,每一条TCP连接有两个端点,TCP连接的端点叫做套接字插口,端口号拼接到IP地址即构成了套接字:套接字socket = (IP地址:端口号)

每一条TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定,即:

TCP连接 ::= {socket1, socket2} = {(IP1:port1),(IP2:port2)}

可靠传输的工作原理

TCP发送的报文段是交给IP层传送的,但IP层只能提供尽最大努力服务,即TCP下面的网络所提供的是不可靠的传输。TCP必须采用适当的措施才能使得两个传输层之间的通信变得可靠。

停止等待协议

image-20201031143215751

可靠传输协议的设计:A只要超过了一段时间仍然没有收到确认,就认为刚才发送的分组丢失了,因而重传前面发过的分组,即超时重传。要实现超时重传,就要在每发送完一个分组时设置一个超时计时器。

需要注意三点:

  1. A在发送完一个分组后,必须暂时保留已发送的分组的副本
  2. 分组和确认分组都必须进行编号
  3. 超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些

image-20201031143634601

确认丢失时:

  1. 丢弃这个重复的分组M1,不向上层交付
  2. 向A发送确认

确认和重传机制,使得可以在不可靠的传输网络上实现可靠的通信。

可靠传输协议常称为自动重传请求ARQ:重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组。

image-20201031144151737

$信道利用率U = {T_D \over T_D + RTT + T_A}$

image-20201031144206600

连续ARQ协议

image-20201031144747565

连续ARQ协议规定:发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。图中原来已经发送了前5个分组,那么现在可以发送第6个分组了。

接收方一般采用累积确认的方式:接收方不必对收到的分组逐个发送确认,而是在收到几个分组后,对按序到达的最后一个分组发送确认,表示到这个分组为止的所有分组都已正确收到了。

累积确认:

  • 优点:容易实现,即使确认丢失也不必重传。
  • 缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息。

TCP报文段的首部格式

TCP是面向字节流的,但是TCP传送的数据单元却是报文段。TCP首部的固定长度(最小长度)是20字节,整个首部的长度是4字节的整数倍。

image-20201031150431371

TCP可靠传输的实现

TCP的滑动窗口是以字节为单位的。

image-20201031153801209

发送窗口的位置由窗口的前沿和后沿的位置共同确定:

  • 发送窗口的后沿的变化情况有两种:
    • 不动:没有收到新的确认
    • 前移:收到了新的确认
  • 发送窗口的的前沿:
    • 通常是不断向前移动:没有收到新的确认,对方通知的窗口大小也不变
    • 也有可能不动:收到了新的确认但对方通知的窗口缩小了,使得发送窗口前沿正好不动
    • 可能向后收缩:发生在对方通知的窗口缩小了。但TCP的标准强烈不赞成这样做。因为很可能发送方在收到这个通知以前已经发送了窗口中的许多数据,现在又要收缩窗口,不让发送这些数据,这样就会产生一些错误。

image-20201031155704324

发送方的应用进程把字节流写入TCP的发送缓存,接收方的应用程序从TCP的接收缓存中读取字节流。

发送缓存用来暂时存放:

  • 发送应用程序传送给发送方TCP准备发送的数据
  • TCP已发送出但尚未收到确认的数据

发送窗口通常只是发送缓存的一部分。已被确认的数据应当从发送缓存中删除,因此发送缓存和发送窗口的后沿是重合的。

接收缓存用来暂时存放:

  • 按序到达的、但尚未被接收应用程序读取的数据
  • 未按序到达的数据

TCP的发送窗口是根据接收窗口设置的,但同一时刻,发送窗口不总是和接收窗口一样大:

  • 通过网络传送窗口值需要经历一定的时间滞后
  • 发送方可能根据网络当时的拥塞情况适当减小自己的发送窗口数值

TCP标准对不按序到达的数据并无明确规定:

  • 如果接收方把不按序到达是数据一律丢弃,则接收窗口的管理会比较简单,但是对网络资源的利用不利
  • TCP通常对不按序到达的数据是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程

TCP要求接收方必须有累积确认的功能,这样可以减少开销:

  • 可以在合适的时候发送确认,但不应该过分推迟发送确认
  • 可以在自己有数据要发送是把确认信息顺便捎带上,该情况实际并不经常发生,因为大多数应用程序很少同时在两个方向上发生数据

TCP的通信是全双工通信,通信中的每一方都在发送和接收报文段,每一方都有自己的发送窗口和接收窗口。

运输层的超时计时器的超时重传时间设置:

  • 报文段的往返时间$RTT$
  • 加权平均往返时间$RTT_S$:
    • 第一次:$RTT_S = RTT样本值$
    • $新的RTT_S = (1-\alpha)\times(旧的RTT_S)+\alpha\times(新的RTT_S样本)$,($0\le\alpha\lt1$,RFC 6298推荐为$\alpha = {1 \over 8}$,即0.125)
  • 超时计时器设置的超时重传时间RTO:$RTO = RTT_S + 4\times RTT_D$
  • $RTT_D$是RTT的偏差的加权平均值:
    • 第一次测量时,为测量到的RTT样本值的一半
    • $新的RTT_D = (1-\beta)\times(旧的RTT_D)+\beta \times|RTT_S - 新的RTT样本|$,$\beta$小于1,推荐值是0.25
  • Karn算法能够使运输层区分开有效的和无效的往返时间样本,从而改进了往返时间的估测,使计算结果更加合理。Karn算法:在计算加权平均$RTT_S$时,只要报文段重传了,就不采用其往返时间样本。这样得出的加权平均$RTT_S$和RTO就较准确;且,报文段每重传一次,就把RTO增大一些,典型的做法是增大为原来的2倍。

当接收方接受到不连续的字节块时,可使用选择确认SACK,此时在建立连接时要在TCP首部的选项中加上“允许SACK”的选项。由于首部选项的长度最多只有40字节,而指明一个边界要用4字节(因为序号有32位),因此在选项中最多只能指明4个字节块的边界信息(8个边界),共用了32字节,另外需要1个字节指明是SACK选项,1个字节指明这个选项占用多少字节。

SACK文档并没有指明发送方应当怎样响应SACK,因此大多数的实现还是重传所有未被确认的数据块。

TCP的流量控制

流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。

image-20201031203010356

发送方的发送窗口不能超过接收方给出的接收窗口的数值。

TCP的窗口单位是字节,不是报文段。

TCP为每一个连接设有一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器,若持续计时器设置的的时间到期,就发送一个零窗口探测报文段(仅携带1字节的数据),而对方就在确认这个探测报文段时给出了现在的窗口值,如果窗口值仍然是零,则重新设置持续计时器。

TCP的拥塞控制

在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况叫做拥塞

所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。

拥塞控制的前提是:网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,设计到所有的主机、所有的路由器,以及降低网络传输性能有关的所有因素。

相反,流量控制往往是指点对点通信量的控制,是个端到端的问题。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

image-20201031213929383

拥塞控制的两大方面:

  • 开环控制:设计网络时事先将有关发生拥塞的因素考虑周到,力求网络在工作时不产生拥塞。但一旦整个系统运行起来,就不再中途进行改正了。
  • 闭环控制:基于反馈环路的概念,主要有几种措施:
    • 监测网络系统以便检测到拥塞在何时、何处发生
    • 把拥塞发生的信息传送到可采取行动的地方
    • 调整网络系统的运行以解决出现的问题

TCP进行拥塞控制的算法有四种:

  • 慢开始
  • 拥塞避免
  • 快重传
  • 快恢复

发送方维持一个叫做拥塞窗口cwnd的状态变量,拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。当接收方总是有足够大的缓存空间时,发送方让自己的发送窗口等于拥塞窗口。

判断网络拥塞的依据就是出现了超时。

image-20201101170414504

相关变量:(用报文段的个数作为窗口大小的单位

  • cwnd:拥塞窗口大小
  • SMSS:发送方的最大报文段
  • ssthresh:慢开始门限,用来防止cwnd增长过大引起网络拥塞
    • 当$cwnd \lt ssthresh$,使用慢开始算法
    • 当$cwnd \gt ssthresh$,停止使用慢开始算法而改用拥塞避免算法
    • 当$cwnd = ssthresh$,既可使用慢开始算法,也可使用拥塞避免算法
  • 传输轮次:一个传输轮次所经历的时间其实就是往返时间RTT。强调:把拥塞窗口cwnd所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认。

慢开始算法:每经过一个传输轮次,拥塞窗口cwnd就加倍。

拥塞避免算法:每经过一个传输轮次,拥塞窗口cwnd就加一。拥塞避免并非完全能够避免了拥塞,是说把拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。

快重传算法可以让发送方尽早知道发生了个别报文段的丢失。快重传算法首先要求对方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。

image-20201101171524869

发送方知道只是丢失了个别的报文段时,不启动慢开始,而是执行快恢复算法:

  • ssthresh = cwnd/2
  • cwnd = ssthresh
  • 执行拥塞避免算法

在拥塞避免阶段,拥塞窗口是按照线性规律增大的,常称为加法增大AI

一旦出现超时或3个重复确认,就要把门限值设置为当前拥塞窗口值的一半,并大大减小拥塞窗口的数值,常称为乘法减小MD

二者合一起就是AIMD算法。

image-20201101171933600

接收方根据自己的接收能力设定了接收方窗口rwnd,并把该窗口值写入TCP首部中的窗口字段,传给发送方。接收方窗口又称为通知窗口。

发送方的发送窗口一定不能够超过对方给出的接收方窗口值rwnd,则:

发送方窗口的上限值=Min[rwnd, cwnd]
  • 当$rwnd \lt cwnd$:接收方的接收能力限制发送方窗口的最大值
  • 当$rwnd \gt cwnd$:网络的拥塞程度限制发送方窗口的最大值
  • rwnd和cwnd中数值较小的一个,控制了发送方发送数据的速率

网络层的策略对TCP拥塞控制影响最大的就是路由器的分组丢弃策略。最简单的情况下是使用尾部丢弃策略,路由器的尾部丢弃往往会导致一连串的分组丢失,使发送方出现超时重传,使TCP进入慢开始状态,尾部丢弃可能同时影响很多条TCP连接,使很多TCP连接在同一时间突然都进入慢开始状态,这在TCP术语中称为全局同步。全局同步使得全网的通信量突然下降很多,而在网络恢复后,其通信量又突然增大很多。

为了避免网络中的全局同步现象,提出了主动队列管理AQM,AQM早期的实现方案是随机早期检测RED

TCP的运输连接管理

TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。

运输连接有三个阶段:连接建立、数据传送、连接释放

运输连接的管理就是使运输连接的建立和释放都能正常进行。

TCP连接的建立采用客户服务器模式:

  • 主动发起连接建立的应用进程叫做客户
  • 被动等待连接建立的应用进程叫做服务器

image-20201101213840232

image-20201101214333994

image-20201101214351953

建立TCP连接时,A最后要发送一次确认,主要是为了防止已失效的连接请求报文段突然又传到了B,因而产生错误。

释放TCP连接时,A要经历2MSL时间的TIME-WAIT状态,理由是:

  • 为了保证A发送的最后一个ACK报文段能够到达B
  • 防止已失效的连接请求报文段出现在本连接中,防止本连接的报文段被下一次TCP连接所接收